""" 
红外接收器

接线:
    IR 红外数据输出 --> GPIO14

"""

from machine import Pin
import time


def bit_reverse_bit(value):
    """ 字节-位反序
    """
    num = 0
    for i in range(8):
        tmp = value & (1 << i)
        if tmp:
            num = num | (1 << (7 - i))
    # print(f"src={bin(value)}, now={bin(num)}")
    return num


def get_one_complement_unsigned(num, bit_length):
    """ 无符号整数反码 
    num : 原始数据
    bit_length: 数据位长度
    """
    # 计算掩码
    mask = (1 << bit_length) - 1
    # 按位异或
    result = num ^ mask
    return result


def iq_irq_handler(ir_pin):
    time_cnt = 0
    recv_data = [0, 0, 0, 0]
    if ir_pin.value() == 0:
        time_cnt = 100
        while (not ir_pin.value()) and time_cnt:
            time.sleep_us(100)
            time_cnt -= 1
            if time_cnt == 0:
                return

        if ir_pin.value() == 1:
            time_cnt = 50
            while ir_pin.value() and time_cnt:
                time.sleep_us(100)
                time_cnt -= 1
                if time_cnt == 0:
                    return

            for i in range(4):
                for j in range(8):
                    # 数据位 0.56ms 低
                    time_cnt = 60
                    while (not ir_pin.value()) and time_cnt:
                        time.sleep_us(100)
                        time_cnt -= 1
                        if time_cnt == 0:
                            return

                    # 数据位 0.56 ~ 1.26ms  高
                    time_cnt = 0
                    while ir_pin.value():
                        time.sleep_us(100)
                        time_cnt += 1
                        if time_cnt > 20:
                            return

                    if time_cnt > 10:
                        recv_data[i] |= 1 << (7 - j)

        if recv_data[2] == get_one_complement_unsigned(recv_data[3], 8):
            print("红外遥控器操作码：0x%02X" % (recv_data[2]))
        else:
            print("计算反码错误 {}".format(recv_data))


ir_pin = Pin(14, Pin.IN, Pin.PULL_UP)
if __name__ == "__main__":
    ir_pin.irq(iq_irq_handler, Pin.IRQ_FALLING)
    while True:
        pass
